package com.ojoin.trade.common_core.utils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import com.ojoin.trade.common.utils.TimeUtils;
import com.ojoin.trade.common.utils.paynow.DateUtil;

/**
 * 节假日 日期公共函数
 * 
 *          public static final int DAY_OF_WEEK_IN_MONTHget 和 set
 *          的字段数字，指示当前月中的第几个星期。 与 DAY_OF_WEEK 字段一起使用时，就可以唯一地指定某月中的某一天。 与
 *          WEEK_OF_MONTH 和 WEEK_OF_YEAR 不同， 该字段的值并不 取决于 getFirstDayOfWeek() 或
 *          getMinimalDaysInFirstWeek()。 DAY_OF_MONTH 1 到 7 总是对应于
 *          DAY_OF_WEEK_IN_MONTH 1；8 到 14 总是对应于 DAY_OF_WEEK_IN_MONTH 2，
 *          依此类推。DAY_OF_WEEK_IN_MONTH 0 表示 DAY_OF_WEEK_IN_MONTH 1 之前的那个星期。
 *          负值是从一个月的末尾开始逆向计数，因此，一个月的最后一个星期天被指定为 DAY_OF_WEEK = SUNDAY,
 *          DAY_OF_WEEK_IN_MONTH = -1。因为负值是逆向计数的，所以它们在月份中的对齐方式通常与正值的不同。
 *          例如，如果一个月有 31 天，那么 DAY_OF_WEEK_IN_MONTH -1 将与 DAY_OF_WEEK_IN_MONTH 5
 *          和 DAY_OF_WEEK_IN_MONTH 4 的末尾相重叠。
 */
public class HolidayUtil {
	private static List<Calendar> holidayList;
	private static boolean holidayFlag;

	/**
	 * 计算工作日 具体节日包含哪些,可以在HolidayMap中修改
	 * 
	 * @param src 日期(源)
	 * @param adddays 要加的天数
	 */
	public static String addDateByWorkDay(String currdate, int adddays) {
		Calendar src = new GregorianCalendar();
		src.setTime(TimeUtils.getDate(currdate));
		
		holidayFlag = false;
		
		int absdays = Math.abs(adddays);
		for (int i = 0; i < absdays; i++) {
			// 把源日期加一天
			if (adddays > 0) {
				src.add(Calendar.DAY_OF_MONTH, 1);
			} else {
				src.add(Calendar.DAY_OF_MONTH, -1);
			}
			holidayFlag = checkHoliday(src);
			if (holidayFlag) {
				i--;
			}
		}
		
		Date resultdate = src.getTime(); // 这个时间就是日期往后推一天的结果
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(resultdate);
	}

	/**
	 * 校验指定的日期是否在节日列表中 具体节日包含哪些,可以在HolidayMap中修改
	 * 
	 * @param src 要校验的日期(源)
	 */
	public static boolean checkHoliday(Calendar src) {
		boolean result = false;
		if (holidayList == null) {
			initHolidayList();
		}
		// 先检查是否是周六周日(有些国家是周五周六)
		if (src.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || 
			 src.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			return true;
		}
		for (Calendar c : holidayList) {
			if (src.get(Calendar.MONTH) == c.get(Calendar.MONTH) && 
				src.get(Calendar.DAY_OF_MONTH) == c.get(Calendar.DAY_OF_MONTH)) {
				result = true;
			}
		}
		return result;
	}

	/**
	 * 初始化节日List,如果需要加入新的节日,请在这里添加 加的时候请尽量使用Calendar自带的常量而不是魔鬼数字
	 * 注:年份可以随便写,因为比的时候只比月份和天
	 * 
	 * @version [s001, 2010-11-19]
	 * @author shenjunjie
	 */
	private static void initHolidayList() {
		holidayList = new ArrayList();

		// 五一劳动节
		Calendar may1 = Calendar.getInstance();
		may1.set(Calendar.MONTH, Calendar.MAY);
		may1.set(Calendar.DAY_OF_MONTH, 1);
		holidayList.add(may1);

		Calendar may2 = Calendar.getInstance();
		may2.set(Calendar.MONTH, Calendar.MAY);
		may2.set(Calendar.DAY_OF_MONTH, 2);
		holidayList.add(may2);

		Calendar may3 = Calendar.getInstance();
		may3.set(Calendar.MONTH, Calendar.MAY);
		may3.set(Calendar.DAY_OF_MONTH, 3);
		holidayList.add(may3);

		// 设置2017元旦为节假日
		Calendar h3 = Calendar.getInstance();
		h3.set(2017, 1, 1);
		holidayList.add(h3);

		// 设置2017年圣诞节为节假日
		// Calendar h4 = Calendar.getInstance();
		// h4.set(2000, 12, 25);
		// holidayList.add(h4);

		// //中国母亲节：五月的第二个星期日
		// Calendar may5 = Calendar.getInstance();
		// //设置月份为5月
		// may5.set(Calendar.MONTH,Calendar.MAY);
		// //设置星期:第2个星期
		// may5.set(Calendar.DAY_OF_WEEK_IN_MONTH,2);
		// //星期日
		// may5.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
		// holidayList.add(may5);
	}
	
	public static void main(String[] args) {
//		Calendar src1 = Calendar.getInstance();
//        src1.set(2016, Calendar.JULY , 1);
//        Calendar result1 = HolidayUtil.addDateByWorkDay(src1, 2);
//        System.out.println(result1.getTime().toString());
//        
//        Calendar src2 = Calendar.getInstance();
//        src2.set(2016, Calendar.JULY , 5);
//        Calendar result2 = HolidayUtil.addDateByWorkDay(src2, -2);
//        System.out.println(result2.getTime().toString());
		
		String r1 = HolidayUtil.addDateByWorkDay("2016-07-02", 2);
		String r2 = HolidayUtil.addDateByWorkDay("2016-07-05", -2);
		
		System.out.println(r1);
		System.out.println(r2);
	}
	
}